package com.ll.app.filter;

import com.alibaba.fastjson.JSON;
import com.ll.base.dto.ApiResultDTO;
import com.ll.base.enums.ResultCodeEnum;
import com.ll.base.exception.CustomRunTimeException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

@Slf4j
@Aspect
@Component
public class ControllerLogAspect {


    /**
     * 请求拦截处理 用于拦截service层记录异常日志
     */
    @Around("execution(public * com.ll.app.controller.*.*(..))")
    public Object doBefore(ProceedingJoinPoint joinPoint) {
        String traceId = UUID.randomUUID().toString();
        StopWatch watch = new StopWatch(traceId);
        watch.start();

        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String parm = null;
        if(joinPoint.getArgs() != null && joinPoint.getArgs().length > 0){
            parm =  JSON.toJSONString(joinPoint.getArgs()[0]);
        }
        // 记录下请求内容
        String url = request.getRequestURL().toString();
        log.info("{} REQ_URL:{} \n Args:{} ", traceId, url, parm);
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
        }catch (CustomRunTimeException ce){

            ApiResultDTO<Object> failure = ApiResultDTO.failure(ce);
            watch.stop();
            log.error("{} RESP_URL:{} ,Time {} \n result:{} ", traceId, url, watch.getLastTaskTimeMillis(), JSON.toJSONString(failure), ce);
            return failure;
        } catch (Throwable throwable) {

            watch.stop();
            log.error("{} RESP_URL:{} ,Time {} \n ", traceId, url, watch.getLastTaskTimeMillis(), throwable);
            return ApiResultDTO.failure(ResultCodeEnum.SYSTEM_ERROR);
        }
        watch.stop();
        log.info("{} RESP_URL:{} ,Time {} \n result:{} ", traceId, url, watch.getLastTaskTimeMillis(), JSON.toJSONString(proceed));
        return proceed;

    }


}